home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
telecomm
/
sticpsrc.lzh
/
SOURCE.ARC
/
RCMD.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-08-25
|
6KB
|
240 lines
/* remote command server */
#include <stdio.h>
#include "global.h"
#include "mbuf.h"
#include "netuser.h"
#include "timer.h"
#include "tcp.h"
#include "password.h"
#include "rcmd.h"
#include "cmdparse.h"
static struct tcb *rcmd_tcb; /* SERVER prototype tcb */
static char *rcmd_paswrd = NULLCHAR; /* password for rcmd */
static struct mbuf *rcmdbuf = NULLBUF; /* output buffer for rcmdputc */
static struct mbuf *rcmdout = NULLBUF; /* chain of rcmd output bufs */
static void rcmd_recv(),rcmd_state();
static int rcmdputc();
extern char version[]; /* program version */
extern char hostname[]; /* hostname to use in prompt */
extern char prompt[]; /* the net> prompt */
extern char nospace[]; /* "no space" message */
extern struct cmds cmds[]; /* commands */
/* Start up rcmd server */
rcmd1(argc,argv)
int argc;
char *argv[];
{
struct socket lsocket;
char tos = 0;
if (rcmd_paswrd != NULLCHAR){
free(rcmd_paswrd);
rcmd_paswrd = NULLCHAR;
}
if (argc > 2){
if ((rcmd_paswrd = malloc(strlen(argv[2]) + 1)) == NULLCHAR) {
printf(nospace);
return 1;
}
strcpy(rcmd_paswrd,argv[2]);
}
lsocket.address = ip_addr;
if(argc < 2)
lsocket.port = RCMD_PORT;
else {
if ((lsocket.port = atoi(argv[1])) == 0)
lsocket.port = RCMD_PORT;
}
if(argc > 3)
tos = get_tos(argv[3]);
rcmd_tcb = open_tcp(&lsocket,NULLSOCK,TCP_SERVER,0,rcmd_recv,NULLVFP,rcmd_state,tos,(char *)NULL);
return 0;
}
/* Shut down rcmd server */
rcmd0()
{
if(rcmd_tcb != NULLTCB)
close_tcp(rcmd_tcb);
if (rcmd_paswrd != NULLCHAR){
free(rcmd_paswrd);
rcmd_paswrd = NULLCHAR;
}
return 0;
}
/* rcmd server receiver upcall */
static
void
rcmd_recv(tcb,cnt)
struct tcb *tcb;
int16 cnt;
{
struct rcmd *rcmd;
struct mbuf *bp;
#ifdef MWC
int (*save_pt)();
#else
# if (defined(MSDOS) && !defined(MSC) && !defined(__TURBOC__))
extern int (*put_stdout)();
# else
int c, save_handle;
# ifdef MSC
char *tmpfilename;
# else
char tmpfilename[L_tmpnam];
# endif
# endif
#endif
char cmdline[RCMD_LINE];
rcmd = (struct rcmd *) tcb->user; /* get control block */
if(recv_tcp(tcb,&bp,cnt) > 0){
append(&rcmd->input,bp); /* append received bytes */
tcp_output(tcb); /* ack the received data */
fflush(stdout); /* make sure stdout is flushed */
#ifdef MWC
save_pt = stdout->_pt; /* save current stdout putc */
stdout->_pt = rcmdputc; /* set stdout putc routine */
#else
# if (defined(MSDOS) && !defined(MSC) && !defined(__TURBOC__))
put_stdout = rcmdputc; /* set stdout putc routine */
# else
/* a portable way is to open a file on (ram) disk */
save_handle = dup(fileno(stdout)); /* save stdout */
# ifdef MSC
tmpfilename = tempnam(NULL,"rcmd");
# else
tmpnam(tmpfilename);
# endif
freopen(tmpfilename,"w+b",stdout);
# endif
#endif
while((bp = pullline(&rcmd->input,0)) != NULLBUF){
cmdline[pullup(&bp,cmdline,sizeof(cmdline) - 1)] = '\0';
free_p(bp);
if (rcmd->pass.okay) {
cmdparse(cmds,cmdline);
printf("%s %s",hostname,prompt);
} else {
if (ok_password(&rcmd->pass,cmdline)) {
log_tcp(tcb,"open rcmd %d",tcb->conn.local.port);
printf("%s %s",hostname,prompt);
} else {
log_tcp(tcb,"fail rcmd %d",tcb->conn.local.port);
printf("sorry\n");
}
}
}
#ifdef MWC
stdout->_pt = save_pt;
#else
# if (defined(MSDOS) && !defined(MSC) && !defined(__TURBOC__))
put_stdout = (int (*)()) 0; /* go back to default stdout */
# else
fseek(stdout,0L,0);
while((c = getc(stdout)) != EOF)
rcmdputc(c); /* copy tmpfile in rcmdbuffer */
fseek(stdout,0L,0); /* don't write to disk */
fflush(stdout);
dup2(save_handle,fileno(stdout));
unlink(tmpfilename); /* remove file */
close(save_handle);
# endif
#endif
append(&rcmdout,rcmdbuf);
send_tcp(tcb,rcmdout);
rcmdout = rcmdbuf = NULLBUF;
}
if (!rcmd->pass.okay)
close_tcp(tcb);
}
/* character output routine for use in rcmd server */
static
int
rcmdputc (c,outfile)
int c;
FILE *outfile;
{
if (c == '\n')
rcmdputc('\r',outfile);
if (rcmdbuf == NULLBUF &&
(rcmdbuf = alloc_mbuf(RCMD_OBUF)) == NULLBUF)
return EOF;
rcmdbuf->data[rcmdbuf->cnt++] = c;
if (rcmdbuf->cnt >= rcmdbuf->size){
append(&rcmdout,rcmdbuf);
rcmdbuf = NULLBUF;
}
return (c);
}
/* Log connection state changes; also respond to remote closes */
static
void
rcmd_state(tcb,old,new)
register struct tcb *tcb;
char old,new;
{
char buf[256];
struct rcmd *rcmd;
switch(new){
case ESTABLISHED:
if((rcmd = (struct rcmd *) calloc(1,sizeof(struct rcmd))) == NULLRCMD){
/* No space, kill connection */
close_tcp(tcb);
return;
}
rcmd->conn = tcb; /* Downward link */
tcb->user = (char *)rcmd; /* Upward link */
if ((rcmd->pass.paswrd = rcmd_paswrd) == NULLCHAR){
log_tcp(tcb,"open rcmd %d (no pw)",tcb->conn.local.port);
rcmd->pass.okay = 1;
sprintf(buf,"rcmd %s\r\n%s %s",version,hostname,prompt);
} else {
sprintf(buf,"rcmd %s %s\r\n%s\r\n",version,hostname,
gen_challenge(&rcmd->pass));
}
send_tcp(tcb,qstring(buf));
break;
case CLOSE_WAIT:
close_tcp(tcb);
break;
case CLOSED:
if(tcb != rcmd_tcb)
log_tcp(tcb,"close rcmd %d",tcb->conn.local.port);
if (tcb->user != NULLCHAR)
free(tcb->user);
del_tcp(tcb);
/* Clean up if server is being shut down */
if(tcb == rcmd_tcb)
rcmd_tcb = NULLTCB;
break;
}
}